package org.graduation.IM.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
import org.graduation.IM.service.MessageService;
import org.graduation.IM.service.socket.SocketService;
import org.graduation.model.common.IM.Message;
import org.graduation.model.common.ResponseResult;
import org.graduation.utils.Token;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RequestMapping("/IM/message")
@RestController
@Slf4j
public class MessageController {
    @Autowired
    private SocketService socketService;
    @Autowired
    private MessageService messageService;
    @Autowired
    private Token tokenTool;
    @Autowired
    private RedisTemplate redisTemplate;
    private final static String REDIS_KEY = "message:";

    @PostMapping("/send")
    public ResponseResult sendMessage(@RequestBody Message message, @RequestHeader("Authorization") String tokenStr) {
        message.setFromUid(tokenTool.getUidByToken(tokenStr));
        socketService.sendMessage(message);
        return ResponseResult.success(message);
    }

    @GetMapping("/history/{uid}/{page}/{size}")
    public ResponseResult<List<Message>> history(@RequestHeader("Authorization") String tokenStr, @PathVariable Integer uid, @PathVariable Integer page, @PathVariable Integer size) {
        Integer userUid = tokenTool.getUidByToken(tokenStr);
        List<Message> result = redisTemplate.opsForList().range(getRedisKey(userUid, uid), (page-1) * size, page * size);
        if (result != null && !result.isEmpty()) {
            log.debug("缓存命中: {}", getRedisKey(userUid, uid));
            // 不是空，提前返回
            return ResponseResult.success(result);
        }
        // 缓存没数据，从数据库中获取
        log.info("缓存没命中:{}", getRedisKey(userUid, uid));
        LambdaQueryWrapper<Message> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper
                .eq(Message::getFromUid, userUid)
                .eq(Message::getToUid, uid)
                .or()
                .eq(Message::getFromUid, uid)
                .eq(Message::getToUid, userUid)
                .orderByAsc(Message::getTime)
        ;
        Page<Message> page_ = new Page<>(page,size);
        page_ = messageService.page(page_, queryWrapper);
        if (!(page_.getRecords().size() < size)) {
            for (Message message : page_.getRecords()) {
                redisTemplate.opsForList().rightPush(getRedisKey(message.getFromUid(), message.getToUid()), message);
            }
        }
        return ResponseResult.success(page_.getRecords());
    }

    private String getRedisKey(Integer uidA, Integer uidB) {
        if (uidA > uidB) {
            return REDIS_KEY + uidB + "&" + uidA;
        }
        return REDIS_KEY + uidA + "&" + uidB;
    }
}
